package cn.ydxiaoshuai.pdf;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import cn.ydxiaoshuai.pdf.diyUtils.PDFSignData;
import cn.ydxiaoshuai.pdf.diyUtils.PDFTextField;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Image;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.*;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @ClassName PDFFormUtil
 * @description: PDF表单处理工具类
 * @author: 小帅丶
 * @create: 2024-11-19 14:57
 * @Version 1.0
 **/
public class PDFFormUtil {
    /**
     * @Description 读取pdf表单中所有文本框的位置信息
     * @param pdfPath pdf文件路径 已处理过的
     * @Author 小帅丶
     * @Date  2024/11/19 0019 15:38:16
     * @return java.util.List<cn.ydxiaoshuai.pdf.diyUtils.PDFTextField>
     **/
    public static List<PDFTextField> readFormTextFieldPosition(String pdfPath) throws Exception{
        PdfReader pdfReader = new PdfReader(pdfPath);
        AcroFields form = pdfReader.getAcroFields();
        List<PDFTextField> pdfTextFieldList = new ArrayList<>();
        for (String key : form.getFields().keySet()) {
            List<AcroFields.FieldPosition> fieldPositions = form.getFieldPositions(key);
            Rectangle position = fieldPositions.get(0).position;
            Rectangle rectangle = new Rectangle(position.getLeft(), position.getBottom(),
                    position.getRight(), position.getTop());
            PDFTextField pdfTextField = new PDFTextField(rectangle,
                    key, fieldPositions.get(0).page);
            pdfTextFieldList.add(pdfTextField);
        }
        return pdfTextFieldList;
    }
    /**
     * @Description 给pdf填充内容
     * @param templatePath 模板pdf文件路径
     * @param newPath 填充后pdf文件保存的路径
     * @param bfChinese 字体
     * @param fontSize 字体大小
     * @param tagValuesMap 填充内容
     * @param pdfSignDataList 签名数据
     * @Author 小帅丶
     * @Date  2024/11/19 0019 14:26:18
     * @return void
     **/
    public static void fillData(String templatePath,
                                String newPath,
                                BaseFont bfChinese,
                                float fontSize,
                                Map<String, String> tagValuesMap,
                                List<PDFSignData> pdfSignDataList) throws Exception{
        PdfReader pdfReader = new PdfReader(templatePath);
        PdfStamper pdfStamper = new PdfStamper(pdfReader, new FileOutputStream(newPath));
        AcroFields form = pdfStamper.getAcroFields();
        for (String key : form.getFields().keySet()) {
            String value = tagValuesMap.get(key);
            if (StrUtil.isNotEmpty(value)) {
                form.setFieldProperty(key, "textfont", bfChinese, null);
                form.setFieldProperty(key, "textsize", fontSize, null);
                form.setField(key, value);
            }
        }
        //是否有签名
        if(CollUtil.isNotEmpty(pdfSignDataList)){
            for (PDFSignData pdfSignData : pdfSignDataList) {
                // 创建图片对象
                Image image = Image.getInstance(pdfSignData.getImgUrl());
                com.itextpdf.text.pdf.PdfContentByte contentByte = pdfStamper.getOverContent(pdfSignData.getPageNum());
                image.scaleToFit(pdfSignData.getFitWidth(),pdfSignData.getFitHeight());
                image.setAbsolutePosition(pdfSignData.getAbsoluteX(), pdfSignData.getAbsoluteY());
                // 将图片添加到内容字节中
                contentByte.addImage(image);
            }
        }
        //是否应该被“展平” 默认给true
        pdfStamper.setFormFlattening(true);
        pdfStamper.close();
        pdfReader.close();
    }
    /**
     * @Description : 创建pdf表单
     * @param sourcePath 源pdf路径-模板PDF
     * @param targetPath 目标pdf路径-填充表单参数后的PDF
     * @Author 小帅丶
     * @Date  2024/11/19 15:29:26
     * @return void
     **/
    public static void creatPdfFormTextField(String sourcePath,
                                             String targetPath,
                                             List<PDFTextField> pdfTextFieldList) throws IOException, DocumentException {
        PdfReader pdfReader = new PdfReader(sourcePath);
        PdfStamper pdfStamper = new PdfStamper(pdfReader, new FileOutputStream(targetPath));
        for (PDFTextField pdfTextField : pdfTextFieldList) {
            TextField textField = new TextField(pdfStamper.getWriter(), pdfTextField.getRectangle(), pdfTextField.getFieldName());
            textFieldGeneral(textField);
            pdfStamper.addAnnotation(textField.getTextField(), pdfTextField.getPageNum());
        }
        pdfStamper.close();
        pdfReader.close();
    }

    private static void textFieldGeneral(TextField textField) {
        textField.setOptions(TextField.HIDDEN);
        // textField.setOptions(TextField.HIDDEN);//文本域不可见
        // textField.setOptions(TextField.VISIBLE_BUT_DOES_NOT_PRINT);//该字段可见，但不打印。
        // textField.setOptions(TextField.HIDDEN_BUT_PRINTABLE);//该字段不可见，但不打印。
        // textField.setOptions(TextField.HIDDEN_BUT_PRINTABLE);//该字段不可见，但不打印。
        // textField.setOptions(TextField.READ_ONLY);//只读
        // textField.setOptions(TextField.REQUIRED);//该字段在通过提交表单操作导出时必须具有值。
        // textField.setOptions(TextField.MULTILINE);//规定区域内可以换行显示
        // textField.setOptions(TextField.DO_NOT_SCROLL);//文本域不会有滚动条,对于单行字段为水平，对于多行字段为垂直,一旦区域满了，将不会再接受任何文字。
        // textField.setOptions(TextField.PASSWORD);//该字段用于输入安全密码，该密码不应该被可视地显示在屏幕上。
        // textField.setOptions(TextField.FILE_SELECTION);//个人理解好像是上传文件，不是很理解
        // textField.setOptions(TextField.DO_NOT_SPELL_CHECK);//无拼写检查
        // textField.setOptions(TextField.EDIT);//如果设置组合框包括一个可编辑的文本框以及一个下拉列表;如果清楚，它只包括一个下拉列表。这个标志只对组合字段有意义。
        // textField.setOptions(TextField.MULTISELECT);//不管列表是否可以有多个选择。仅适用于/ ch列表字段，而不适用于组合框。
        // textField.setOptions(TextField.COMB);//组合框标志。
    }
}
